globalZoneOperator = operator;
globalZones = [];
globalZonePolygone = null;
globalZoneMap = null;

function loadGlobalZone(globalZoneMap_, globalZoneOperator_) {
    adminReport("Chargement de la zone globale");
    globalZoneMap = globalZoneMap_;
    globalZoneOperator = globalZoneOperator_;
    $.get("rest/globalZone/findall?operator=" + globalZoneOperator, function(data) {
        if (data.trim().length > 0) {
            addMarkersGlobalZone(JSON.parse(data.trim()));
            onLoadGlobalZone();
        }
    });
}

function saveGlobalZone() { 
    json = JSON.stringify(getJsonGlobalZone());
    console.log('Sauvegarde de la zone globale Global:' + json);
    XHRpost("rest/globalZone/create",
            {
                data: JSON.stringify(getJsonGlobalZone()),
                operator: globalZoneOperator
            },
    function(res) {
        adminReport('Sauvegarde de la zone globale Global Zone');
    }
    )
}
 
function onLoadGlobalZone() {
    drawPolygonGlobalZone();
}

function reDrawPolygonGlobalZone() {
    clearPolygonGlobalZone();
    drawPolygonGlobalZone();
}

function drawBoundsGlobalZone() {
    for (var i = 0; i < globalZones.length; i++) {
        globalZones[i].setMap(globalZoneMap);
    }
}
 
function drawPolygonGlobalZone() {
    var tmp = [];
    for (var i = 0; i < globalZones.length; i++) {
        var borne = globalZones[i];
        tmp.push(new google.maps.LatLng(borne.info.lat, borne.info.lng));
    }
    tmp.push(tmp[0]);
    globalZonePolygone = new google.maps.Polyline({
        path: tmp,
        clickable: false,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
        fillColor: '#EE99EE',
        fillOpacity: 0.2
    });
    globalZonePolygone.setMap(globalZoneMap);
}

function clearMarkerGlobalZone() {
    for (var i = 0; i < globalZones.length; i++) {
        globalZones[i].setMap(null);
    }
}

function clearPolygonGlobalZone() {
    if (globalZonePolygone)
        globalZonePolygone.setMap(null);
}

function addMarkersGlobalZone(bounds) {
    for (var i = 0; i < bounds.length; i++) {
        addMarkerGlobalZone(
                nThObject(bounds[i],1), 
                nThObject(bounds[i],2), 'Borne ' + i);
    }
}
/**
 *  Add new bound to an existing GZ - call from external cmd
 */
function newMarkersGlobalZone(lat, lng) {
    addMarkerGlobalZone(lat, lng);
    onGlobalZoneBoundChanged();
}

function addMarkerGlobalZone(lat, lng) {
    console.log('Chargement Borne de Zone Globale Lat=' + lat + ' Lng=' + lng);
    var title = 'Borne ' + globalZones.length;
    
    var marker = new google.maps.Marker({
        position: new google.maps.LatLng(lat, lng),
        map: globalZoneMap,
        draggable: true,
        title: title,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    });
    marker.setIcon('/supervision/images/borne.png');
    marker.setMap(globalZoneMap);
    
    var zone = new GlobalZone(marker, {
        reference: 'Borne ' + globalZones.length,
        lat:lat,
        lng:lng
    });
    
    google.maps.event.addListener(marker, 'click', function() {

        if (confirm('Suppression de la borne ?')) {
            
            var index = globalZones.indexOf(zone);
            if (index > -1) {
                globalZones.splice(index, 1);
            }
            marker.setMap(null);
            onGlobalZoneBoundChanged();
        }

    });
    google.maps.event.addListener(marker, 'dragend', function() {
        var pos = zone.marker.position;
        var lat = nThObject(pos, 1);
        var lng = nThObject(pos, 2);
        zone.info.lat=lat;
        zone.info.lng=lng;  
        onGlobalZoneBoundChanged();
    });
    globalZones.push(zone);
}


function getJsonGlobalZone() {
    var tmp = [];
    for (var i = 0; i < globalZones.length; i++) {
        tmp.push(globalZones[i].getJson());
    }
    return tmp;
}

function onGlobalZoneBoundChanged() {
    var jarv = jarvis_(copy(globalZones));
    if (jarv.length == globalZones.length) {
        clearMarkerGlobalZone();
        clearPolygonGlobalZone();
        //saveGlobalZone();
        drawBoundsGlobalZone();
        drawPolygonGlobalZone();
    } else {
        clearMarkerGlobalZone();
        clearPolygonGlobalZone();
        globalZones = jarv;
        //saveGlobalZone();
        drawBoundsGlobalZone();
        drawPolygonGlobalZone();
    }
}

function jarvis_(points) { 
    if (points.length < 3)
        return points;

    var pointOnHull = points[0]; 
    for (var i = 1; i < points.length; i++) {
        if (pointOnHull.info.lng > points[i].info.lng) {
            pointOnHull = points[i];
        }
    }
    var result = [];
    result.push(pointOnHull);
    var p = pointOnHull;
    var guard = 0;
    do {
        guard++;
        var rest = copy(points);
        var v = rest.pop();
        if (p == v)
            v = rest.pop();
        while (rest.length > 0) {
            var q = rest.pop();
            if (pvq(p, v, q)) {
                v = q;
            }
        }
        result.push(v);
        p = v;
    } while (v != pointOnHull && guard < 100);
    result.pop();
    return result;
}


// vrai so pvq tourne dans le sens invers des aiguille d'une montre
// -> q est à gauche de la ligne (p-v)
function pvq(p, v, q) {
    return (q.info.lng - p.info.lng) * (v.info.lat - p.info.lat) - (v.info.lng - p.info.lng) * (q.info.lat - p.info.lat) < 0;
}

function copy(array) {
    var clone = [];
    for (var i = 0; i < array.length; i++) {
        clone.push(array[i]);
    }
    return clone;
}